package com.iotechn.unimall.admin.api.settingsImage;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.iotechn.unimall.core.exception.AdminServiceException;
import com.iotechn.unimall.core.exception.ExceptionDefinition;
import com.iotechn.unimall.core.exception.ServiceException;
import com.iotechn.unimall.data.component.CacheComponent;
import com.iotechn.unimall.data.domain.SettingsImageDO;
import com.iotechn.unimall.data.mapper.SettingsImageMapper;
import com.iotechn.unimall.data.model.Page;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;


@Service
public class AdminSettingsImageServiceImpl implements AdminSettingsImageService {

    private static final String Enterprise_IMAGES_GROUP = "CA_Enterprise_IMAGES_GROUP";

    @Autowired
    private SettingsImageMapper settingsImageMapper;
    @Autowired
    private CacheComponent cacheComponent;

    public enum IMAGE_TYPE {
        HOME_LOGO(1),
        HOME_BANNER(2),
        HOME_OTHER(3),
        NEWS_BANNER(4),
        HOME_WECHAT(5),
        ;
        public int CODE;
        IMAGE_TYPE(int code) {
            this.CODE = code;
        }
    }

    @Override
    public Page<SettingsImageDO> list(Integer page, Integer limit, String location, String name, Long adminId) throws ServiceException {
        Wrapper<SettingsImageDO> wrapper = new EntityWrapper<SettingsImageDO>();
        if (!StringUtils.isEmpty(name))
            wrapper.like("name", name);
        if (!StringUtils.isEmpty(location))
            wrapper.eq("location", location);
        wrapper.orderBy("id", false);
        Integer count = settingsImageMapper.selectCount(wrapper);
        List<SettingsImageDO> SettingsImageDOS = settingsImageMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
        return new Page<>(SettingsImageDOS, page, limit, count);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SettingsImageDO create(SettingsImageDO settingsImageDO, Long adminId) throws ServiceException {
        check(settingsImageDO,SqlCommandType.INSERT);
        Date now = new Date();
        now = DateUtils.round(now, Calendar.SECOND);
        settingsImageDO.setGmtCreate(now);
        settingsImageDO.setGmtUpdate(now);
        settingsImageDO.setIsUse(0);
        if (settingsImageMapper.insert(settingsImageDO) > 0) {
            settingsImageDO.setId(settingsImageDO.getId());
            cacheComponent.putZsetRaw(Enterprise_IMAGES_GROUP, settingsImageDO, (double) (settingsImageDO.getLocation() * 100 + settingsImageDO.getOrder()));
            return settingsImageDO;
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String update(SettingsImageDO settingsImageDO, Long adminId) throws ServiceException {
        check(settingsImageDO,SqlCommandType.UPDATE);
        Long id = settingsImageDO.getId();
        if (id == null) return "fail";
        Date now = new Date();
        now = DateUtils.round(now, Calendar.SECOND);
        settingsImageDO.setGmtUpdate(now);
        settingsImageDO.setIsUse(0);
        SettingsImageDO imageDO = settingsImageMapper.selectById(id);
        if (settingsImageMapper.updateById(settingsImageDO) > 0) {
            cacheComponent.removeZsetRaw(Enterprise_IMAGES_GROUP, imageDO, (double) (settingsImageDO.getLocation() * 100 + settingsImageDO.getOrder()));
            cacheComponent.putZsetRaw(Enterprise_IMAGES_GROUP, settingsImageDO, Double.valueOf(settingsImageDO.getLocation() * 100 + settingsImageDO.getOrder()));
            return "ok";
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String delete(Long id, Long adminId) throws ServiceException {
        SettingsImageDO imageDO = settingsImageMapper.selectById(id);
        if (settingsImageMapper.deleteById(id) > 0) {
            cacheComponent.removeZsetRaw(Enterprise_IMAGES_GROUP, imageDO, (double) (imageDO.getLocation() * 100 + imageDO.getOrder()));
            return "ok";
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    public SettingsImageDO detail(Long id, Long adminId) throws ServiceException {
        return settingsImageMapper.selectById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String batchDelete(String idsJson, Long adminId) throws ServiceException {
        List<Long> ids = JSONObject.parseArray(idsJson, Long.class);
        if (CollectionUtils.isEmpty(ids)) {
            throw new AdminServiceException(ExceptionDefinition.IMAGE_NOT_EXIST);
        }
        List<SettingsImageDO> list = settingsImageMapper.selectBatchIds(ids);
        if (settingsImageMapper.delete(new EntityWrapper<SettingsImageDO>().in("id", ids)) <= 0) {
            throw new AdminServiceException(ExceptionDefinition.IMAGE_NOT_EXIST);
        }
        list.forEach(i -> cacheComponent.removeZsetRaw(Enterprise_IMAGES_GROUP, i, (double) (i.getLocation() * 100 + i.getOrder())));
        return "ok";
    }

    @PostConstruct
    public void init(){
        // 清除原始内容
        cacheComponent.del(Enterprise_IMAGES_GROUP);
        List<SettingsImageDO> list = settingsImageMapper.selectList(new EntityWrapper<>());
        list.forEach(i -> cacheComponent.putZsetRaw(Enterprise_IMAGES_GROUP, i, Double.valueOf(i.getLocation() * 100 + i.getOrder())));
    }

    private void check(SettingsImageDO settingsImageDO, SqlCommandType sqlCommandType) throws ServiceException {
        Set<SettingsImageDO> set = cacheComponent.getZsetWithScores(Enterprise_IMAGES_GROUP, (double) (IMAGE_TYPE.HOME_LOGO.CODE * 100), SettingsImageDO.class);
        if (!set.isEmpty()
                && settingsImageDO.getLocation() == IMAGE_TYPE.HOME_LOGO.CODE
                && sqlCommandType == SqlCommandType.INSERT){
            throw new AdminServiceException(ExceptionDefinition.IMAGE_LOGO_EXIST);
        }
        set = cacheComponent.getZsetWithScores(Enterprise_IMAGES_GROUP, (double) (IMAGE_TYPE.HOME_WECHAT.CODE * 100), SettingsImageDO.class);
        if (!set.isEmpty()
                && settingsImageDO.getLocation() == IMAGE_TYPE.HOME_WECHAT.CODE
                && sqlCommandType == SqlCommandType.INSERT)
            throw new AdminServiceException(ExceptionDefinition.IMAGE_WECHAT_EXIST);

    }
}
